<?php if (!defined('CORE_DIR')) die('Wrong entry point!');

/* 
 * Copyright 2010 Anton Muraviev a.k.a kuromaisu
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */

Aero::define('SpecificationLibarySpecification', AS_SINGLETON);

/*
 * SpecificationLibarySpecification
 */
class SpecificationLibarySpecification extends AeroSpec
{
	protected function itShouldBeAbleToDetectThrownExceptions()
	{
		$this->throws('Exception');
		
		throw new Exception();
	}

	protected function itShouldBeAbleToDetectThrownErrors()
	{
		$this->triggers('Some misc error.');
		
		trigger_error('Some misc error.', E_USER_ERROR);
	}
	
	protected function itShouldCheckAssertionsAboutArbitraryValuesAndVariables()
	{
		$null = null;
		$true = true;
		$false = false;
		$object = new STDClass();
		$object2 = new STDClass();
		$object3 =& $object;
		$string = 'Some string';
		$int = 123;
		$int2 = 123;
		$int3 =& $int;
		$float = 123.123;
		$numeric = '123';
		$array = array(123,123);
		
		$this->value($null)
			->is('null')->isNot('string')
			->equals(null)->doesNotEqual(123)
			->isIdenticalTo(null)->isNotIdenticalTo(8);
			
		$this->value($string)->is('string')->equals('Some string');
		
		$this->variable($true)->is('bool')->is('true')->isNot('false');
		$this->variable($false)->is('bool')->is('false')->isNot('true');
		
		$this->isTrue($true);
		$this->isFalse($false);
		
		$this->variable($object)
			->is('object')->equals($object2)
			->isNotIdenticalTo($object2)->references($object3);
		$this->variable($int)->is('integer')->isEqualTo('123')->isIdenticalTo(123)->references($int3);
		
		$this->variable($float)->is('float')->equals(123.123);
		$this->variable($numeric)->is('numeric')->is('string')->equals(123)->isIdenticalTo('123');
		
		$this->variable($array)->is('array');
	}

	protected function itShouldCheckAssertionsAboutIndexedArrays()
	{
		$array = array(125,123,124);
		
		$this->vector($array)->doesNotHaveValueAt(19)->hasValueAt(1)->valueAt(0)->equals(125);
	}
	
	protected function itShouldCheckAssertionsAboutAssociativeArrays()
	{
		$array = array(
			'one' => 125,
			'two' => 123,
			'three'=> 124
		);
		
		$this->dictionary($array)
			->hasKey('three')->doesNotHaveKey('four')
			->valueOf('two')->equals(123);
	}

	protected function itShouldCheckAssertionsAboutStrings()
	{
		$string = 'Some boring not-so-long string... That says "Hi!"';
		
		$this->string($string)->contains('boring')->contains('string')->doesNotContain('fuck')
			->matches('~not-so-long \w+\.+~')
			->doesNotMatch('~\.{4}~');
	}
	
	public $some_test_variable = '123';
	
	protected function itShouldCheckAssertionsAboutObjects()
	{
		$this->object($this)
			->isInstanceOf('AeroSpec')
			->isInstanceOf('SpecificationLibarySpecification')
			->isNotInstanceOf('Aero')
			->hasMethod('initialize')
			->doesNotHaveMethod('destroy')
			->hasProperty('some_test_variable')
			->doesNotHaveProperty('non_existance_variable')
			->property('some_test_variable')->equals(123);
	}

	public function itShouldThrowErrorWhenPageIsNotAvailable()
	{
		$this->triggers('failed to open stream');
		
		$this->page('/non-existant-page');
	}
	
	protected function itShouldCheckAssertionsAboutHTMLCode()
	{
		$this->page('/test_forms')->contains('Typography settings')->doesNotContain('Some garbage');
	}

	protected function itShouldCheckAssertionsAboutHTMLDocumentObjectModel()
	{
		$this->page('/test_forms')->hasElement('h1')->doesNotHaveElement('h6')
			->hasElementWithId('text_field')->doesNotHaveElementWithId('super_duper')
			->matchesSelector('div.field>span.label+label>input[type=radio]')
			->doesNotMatchSelector('#non-existant-id');
	}
}